Uma rede de supermercados viu a necessidade de criar uma maneira de entender e conhecer mais o seu público-alvo. Diante desse desafio, a rede precisa criar um processo de Big Data para auxiliar essa análise. A rede quer conhecer seu cliente como um todo, das compras que foram realizadas aos produtos mais vendidos e, dessa forma, criar uma estrutura que permita tomar decisões mais assertivas.
Os analistas de Big Data da rede identificaram que é necessário desenvolver um processo bem elaborado para transformar dados variados em informações úteis. Para isso é necessário:
Para esse primeiro momento, vamos analisar os dados e realizar um agrupamento dos clientes baseados em algumas características que eles possuem.
As compras foram separadas por usuário. Deste modo, cada compra necessita possuir cliente, produto, quantidade de produtos, valor unitário e valor total da compra.
ATENÇÃO Informação importante: não existe compra sem produto ou sem cliente.
Os dados de clientes e compras é um dado fictício utilizado para o desenvolvimento das atividades a serem realizadas neste trabalho. Deste modo, os dados foram criados de forma aleatória e não possuem nenhuma relação com dados no mundo real.
Atividades do enunciado I Os alunos deverão desempenhar as seguintes atividades:
Coletar dados das seguintes fontes de dados. • compras.xls o Contém dados das compras realizadas por cliente; • clientes.json o Contém dados de clientes (análise de perfil); • estados.txt o Contém dados de estados dos clientes; • O link: https://profleandrolessa.wordpress.com/exercicio-de-coleta-de- dados/ o Contém dados de produtos.
Criar estrutura de armazenamento;
Avaliar dados ausentes das colunas e corrigi-los;
Criar algoritmo de clusterização k-means;
Responder as questões 1 a 10 práticas do desafio.
#Importando as bibliotecas:
import pandas as pd
import json
import csv
#Coleta de dados:
#Dataset compras:
compras_df = pd.read_excel('compras.xls')
compras_df.head()
| cod_cliente | cod_produto | qtd_produto | valor_unitario | valor_total_compra | |
|---|---|---|---|---|---|
| 0 | 1 | 1011.0 | 3 | 5.99 | 17.97 |
| 1 | 2 | 1032.0 | 4 | 9.99 | 39.96 |
| 2 | 3 | 1049.0 | 2 | 5.99 | NaN |
| 3 | 4 | 1021.0 | 4 | 3.99 | 15.96 |
| 4 | 5 | 1001.0 | 4 | 22.00 | 88.00 |
# Dataset mercado:
mercado_df = pd.read_csv('mercado.csv', sep=';')
mercado_df.head(10)
| Id | product_1 | product_2 | product_3 | product_4 | product_5 | product_6 | product_7 | product_8 | product_9 | ... | product_11 | product_12 | product_13 | product_14 | product_15 | product_16 | product_17 | product_18 | product_19 | product_20 | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 0 | 0 | shrimp | almonds | avocado | vegetables mix | green grapes | whole weat flour | yams | cottage cheese | energy drink | ... | low fat yogurt | green tea | honey | salad | mineral water | salmon | antioxydant juice | frozen smoothie | spinach | olive oil |
| 1 | 1 | burgers | meatballs | eggs | NaN | NaN | NaN | NaN | NaN | NaN | ... | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN |
| 2 | 2 | chutney | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | ... | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN |
| 3 | 3 | turkey | avocado | NaN | NaN | NaN | NaN | NaN | NaN | NaN | ... | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN |
| 4 | 4 | mineral water | milk | energy bar | whole wheat rice | green tea | NaN | NaN | NaN | NaN | ... | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN |
| 5 | 5 | low fat yogurt | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | ... | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN |
| 6 | 6 | whole wheat pasta | french fries | NaN | NaN | NaN | NaN | NaN | NaN | NaN | ... | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN |
| 7 | 7 | soup | light cream | shallot | NaN | NaN | NaN | NaN | NaN | NaN | ... | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN |
| 8 | 8 | frozen vegetables | spaghetti | green tea | NaN | NaN | NaN | NaN | NaN | NaN | ... | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN |
| 9 | 9 | french fries | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | ... | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN |
10 rows × 21 columns
# Dataset clientes:
# conversão de json para pandas dataFrame
with open('clientes.json', 'r') as file:
arquivo = file.read()
json_dados = json.loads(arquivo)
json_dados.keys()
dict_keys(['cliente'])
clientes_df = pd.DataFrame(json_dados["cliente"])
clientes_df.head()
| cod_cliente | sexo | idade | qtd_filhos | estado_civil | cod_estado | hipertenso | diabetes | |
|---|---|---|---|---|---|---|---|---|
| 0 | 1 | 1 | 26 | 2 | 3 | 13 | 0 | 1 |
| 1 | 2 | 1 | 58 | 0 | 2 | 2 | 0 | 0 |
| 2 | 3 | 1 | 63 | 1 | 3 | 11 | 1 | 1 |
| 3 | 4 | 1 | 58 | 2 | 2 | 11 | 1 | 1 |
| 4 | 5 | 0 | 70 | 0 | 1 | 5 | 0 | 1 |
# Dataset estados:
# conversão de txt para csv
with open('estados.txt', 'r') as in_file:
stripped = (line.strip() for line in in_file)
lines = (line.split(",") for line in stripped if line)
with open('estados.csv', 'w') as out_file:
writer = csv.writer(out_file)
writer.writerows(lines)
estados_df = pd.read_csv('estados.csv', encoding='latin-1', sep="|")
estados_df.head()
| codigo_estado | nome_estado | sgl_estado | |
|---|---|---|---|
| 0 | 1 | Acre | AC |
| 1 | 2 | Alagoas | AL |
| 2 | 3 | Amapá | AP |
| 3 | 4 | Amazonas | AM |
| 4 | 5 | Bahia | BA |
# Dataset produtos:
# pd.read_html
produtos_df = pd.read_html('https://profleandrolessa.wordpress.com/exercicio-de-coleta-de-dados/', decimal=',', thousands ='.', header = 0)[0]
produtos_df
| cod_produto | nome_produto | cod_classe_produto | classe_produto | valor | |
|---|---|---|---|---|---|
| 0 | 1000 | Sabão em pó | 1 | Produtos de Limpeza | 9.90 |
| 1 | 1001 | Amaciante | 1 | Produtos de Limpeza | 22.00 |
| 2 | 1002 | Detergente | 1 | Produtos de Limpeza | 1.99 |
| 3 | 1003 | Água sanitária | 1 | Produtos de Limpeza | 12.00 |
| 4 | 1004 | Esponja de aço | 1 | Produtos de Limpeza | 4.00 |
| ... | ... | ... | ... | ... | ... |
| 82 | 1082 | Peixe | 5 | Carnes e Frios | 29.99 |
| 83 | 1083 | Frango | 5 | Carnes e Frios | 1.99 |
| 84 | 1084 | Carne vermelha | 5 | Carnes e Frios | 56.99 |
| 85 | 1085 | Carne seca | 5 | Carnes e Frios | 64.99 |
| 86 | 1086 | Salsicha | 5 | Carnes e Frios | 15.90 |
87 rows × 5 columns
# Dataset compras:
compras_df.head()
| cod_cliente | cod_produto | qtd_produto | valor_unitario | valor_total_compra | |
|---|---|---|---|---|---|
| 0 | 1 | 1011.0 | 3 | 5.99 | 17.97 |
| 1 | 2 | 1032.0 | 4 | 9.99 | 39.96 |
| 2 | 3 | 1049.0 | 2 | 5.99 | NaN |
| 3 | 4 | 1021.0 | 4 | 3.99 | 15.96 |
| 4 | 5 | 1001.0 | 4 | 22.00 | 88.00 |
compras_df.info()
<class 'pandas.core.frame.DataFrame'> RangeIndex: 3000 entries, 0 to 2999 Data columns (total 5 columns): # Column Non-Null Count Dtype --- ------ -------------- ----- 0 cod_cliente 3000 non-null int64 1 cod_produto 2990 non-null float64 2 qtd_produto 3000 non-null int64 3 valor_unitario 2995 non-null float64 4 valor_total_compra 2979 non-null float64 dtypes: float64(3), int64(2) memory usage: 117.3 KB
compras_df.describe()
| cod_cliente | cod_produto | qtd_produto | valor_unitario | valor_total_compra | |
|---|---|---|---|---|---|
| count | 3000.000000 | 2990.000000 | 3000.000000 | 2995.000000 | 2979.000000 |
| mean | 1500.500000 | 1043.261873 | 2.507667 | 8.487830 | 21.173031 |
| std | 866.169729 | 24.969114 | 1.119386 | 10.772478 | 30.504863 |
| min | 1.000000 | 1000.000000 | 1.000000 | 1.250000 | 1.250000 |
| 25% | 750.750000 | 1022.000000 | 1.000000 | 3.500000 | 6.000000 |
| 50% | 1500.500000 | 1043.000000 | 3.000000 | 4.990000 | 11.980000 |
| 75% | 2250.250000 | 1065.000000 | 4.000000 | 8.990000 | 22.500000 |
| max | 3000.000000 | 1086.000000 | 4.000000 | 64.990000 | 259.960000 |
compras_df.isna().sum()
cod_cliente 0 cod_produto 10 qtd_produto 0 valor_unitario 5 valor_total_compra 21 dtype: int64
compras_df.dropna(inplace=True, subset=['cod_produto'])
compras_df.isna().sum()
cod_cliente 0 cod_produto 0 qtd_produto 0 valor_unitario 5 valor_total_compra 21 dtype: int64
compras_df["valor_total_compra"].loc[compras_df["valor_total_compra"].isna()] = (compras_df["valor_unitario"]*compras_df["qtd_produto"])
C:\Users\lepae\anaconda3\lib\site-packages\pandas\core\indexing.py:1732: SettingWithCopyWarning: A value is trying to be set on a copy of a slice from a DataFrame See the caveats in the documentation: https://pandas.pydata.org/pandas-docs/stable/user_guide/indexing.html#returning-a-view-versus-a-copy self._setitem_single_block(indexer, value, name)
compras_df.isna().sum()
cod_cliente 0 cod_produto 0 qtd_produto 0 valor_unitario 5 valor_total_compra 0 dtype: int64
compras_df.head()
| cod_cliente | cod_produto | qtd_produto | valor_unitario | valor_total_compra | |
|---|---|---|---|---|---|
| 0 | 1 | 1011.0 | 3 | 5.99 | 17.97 |
| 1 | 2 | 1032.0 | 4 | 9.99 | 39.96 |
| 2 | 3 | 1049.0 | 2 | 5.99 | 11.98 |
| 3 | 4 | 1021.0 | 4 | 3.99 | 15.96 |
| 4 | 5 | 1001.0 | 4 | 22.00 | 88.00 |
compras_df["valor_unitario"].loc[compras_df["valor_unitario"].isna()] = (compras_df["valor_total_compra"]/compras_df["qtd_produto"])
C:\Users\lepae\anaconda3\lib\site-packages\pandas\core\indexing.py:1732: SettingWithCopyWarning: A value is trying to be set on a copy of a slice from a DataFrame See the caveats in the documentation: https://pandas.pydata.org/pandas-docs/stable/user_guide/indexing.html#returning-a-view-versus-a-copy self._setitem_single_block(indexer, value, name)
compras_df.isna().sum()
cod_cliente 0 cod_produto 0 qtd_produto 0 valor_unitario 0 valor_total_compra 0 dtype: int64
# Data set mercado:
mercado_df.head()
| Id | product_1 | product_2 | product_3 | product_4 | product_5 | product_6 | product_7 | product_8 | product_9 | ... | product_11 | product_12 | product_13 | product_14 | product_15 | product_16 | product_17 | product_18 | product_19 | product_20 | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 0 | 0 | shrimp | almonds | avocado | vegetables mix | green grapes | whole weat flour | yams | cottage cheese | energy drink | ... | low fat yogurt | green tea | honey | salad | mineral water | salmon | antioxydant juice | frozen smoothie | spinach | olive oil |
| 1 | 1 | burgers | meatballs | eggs | NaN | NaN | NaN | NaN | NaN | NaN | ... | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN |
| 2 | 2 | chutney | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | ... | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN |
| 3 | 3 | turkey | avocado | NaN | NaN | NaN | NaN | NaN | NaN | NaN | ... | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN |
| 4 | 4 | mineral water | milk | energy bar | whole wheat rice | green tea | NaN | NaN | NaN | NaN | ... | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN |
5 rows × 21 columns
mercado_df.info()
<class 'pandas.core.frame.DataFrame'> RangeIndex: 7501 entries, 0 to 7500 Data columns (total 21 columns): # Column Non-Null Count Dtype --- ------ -------------- ----- 0 Id 7501 non-null int64 1 product_1 7501 non-null object 2 product_2 5747 non-null object 3 product_3 4389 non-null object 4 product_4 3345 non-null object 5 product_5 2529 non-null object 6 product_6 1864 non-null object 7 product_7 1369 non-null object 8 product_8 981 non-null object 9 product_9 654 non-null object 10 product_10 395 non-null object 11 product_11 256 non-null object 12 product_12 154 non-null object 13 product_13 87 non-null object 14 product_14 47 non-null object 15 product_15 25 non-null object 16 product_16 8 non-null object 17 product_17 4 non-null object 18 product_18 4 non-null object 19 product_19 3 non-null object 20 product_20 1 non-null object dtypes: int64(1), object(20) memory usage: 1.2+ MB
mercado_df.isna().sum()
Id 0 product_1 0 product_2 1754 product_3 3112 product_4 4156 product_5 4972 product_6 5637 product_7 6132 product_8 6520 product_9 6847 product_10 7106 product_11 7245 product_12 7347 product_13 7414 product_14 7454 product_15 7476 product_16 7493 product_17 7497 product_18 7497 product_19 7498 product_20 7500 dtype: int64
mercado_df.dropna(thresh=2, inplace= True) #elimina linhas que tenha id mas não tenham produto
mercado_df.isna().sum()
Id 0 product_1 0 product_2 1754 product_3 3112 product_4 4156 product_5 4972 product_6 5637 product_7 6132 product_8 6520 product_9 6847 product_10 7106 product_11 7245 product_12 7347 product_13 7414 product_14 7454 product_15 7476 product_16 7493 product_17 7497 product_18 7497 product_19 7498 product_20 7500 dtype: int64
# Dataset clientes:
clientes_df.head()
| cod_cliente | sexo | idade | qtd_filhos | estado_civil | cod_estado | hipertenso | diabetes | |
|---|---|---|---|---|---|---|---|---|
| 0 | 1 | 1 | 26 | 2 | 3 | 13 | 0 | 1 |
| 1 | 2 | 1 | 58 | 0 | 2 | 2 | 0 | 0 |
| 2 | 3 | 1 | 63 | 1 | 3 | 11 | 1 | 1 |
| 3 | 4 | 1 | 58 | 2 | 2 | 11 | 1 | 1 |
| 4 | 5 | 0 | 70 | 0 | 1 | 5 | 0 | 1 |
clientes_df.info()
<class 'pandas.core.frame.DataFrame'> RangeIndex: 3000 entries, 0 to 2999 Data columns (total 8 columns): # Column Non-Null Count Dtype --- ------ -------------- ----- 0 cod_cliente 3000 non-null int64 1 sexo 3000 non-null int64 2 idade 3000 non-null int64 3 qtd_filhos 3000 non-null int64 4 estado_civil 3000 non-null int64 5 cod_estado 3000 non-null int64 6 hipertenso 3000 non-null int64 7 diabetes 3000 non-null int64 dtypes: int64(8) memory usage: 187.6 KB
clientes_df.isna().sum()
cod_cliente 0 sexo 0 idade 0 qtd_filhos 0 estado_civil 0 cod_estado 0 hipertenso 0 diabetes 0 dtype: int64
# Dataset estados:
estados_df.head()
| codigo_estado | nome_estado | sgl_estado | |
|---|---|---|---|
| 0 | 1 | Acre | AC |
| 1 | 2 | Alagoas | AL |
| 2 | 3 | Amapá | AP |
| 3 | 4 | Amazonas | AM |
| 4 | 5 | Bahia | BA |
estados_df.info()
<class 'pandas.core.frame.DataFrame'> RangeIndex: 27 entries, 0 to 26 Data columns (total 3 columns): # Column Non-Null Count Dtype --- ------ -------------- ----- 0 codigo_estado 27 non-null int64 1 nome_estado 27 non-null object 2 sgl_estado 27 non-null object dtypes: int64(1), object(2) memory usage: 776.0+ bytes
estados_df.isna().sum()
codigo_estado 0 nome_estado 0 sgl_estado 0 dtype: int64
# Dataset produtos:
produtos_df.head()
| cod_produto | nome_produto | cod_classe_produto | classe_produto | valor | |
|---|---|---|---|---|---|
| 0 | 1000 | Sabão em pó | 1 | Produtos de Limpeza | 9.90 |
| 1 | 1001 | Amaciante | 1 | Produtos de Limpeza | 22.00 |
| 2 | 1002 | Detergente | 1 | Produtos de Limpeza | 1.99 |
| 3 | 1003 | Água sanitária | 1 | Produtos de Limpeza | 12.00 |
| 4 | 1004 | Esponja de aço | 1 | Produtos de Limpeza | 4.00 |
produtos_df.info()
<class 'pandas.core.frame.DataFrame'> RangeIndex: 87 entries, 0 to 86 Data columns (total 5 columns): # Column Non-Null Count Dtype --- ------ -------------- ----- 0 cod_produto 87 non-null int64 1 nome_produto 87 non-null object 2 cod_classe_produto 87 non-null int64 3 classe_produto 87 non-null object 4 valor 87 non-null float64 dtypes: float64(1), int64(2), object(2) memory usage: 3.5+ KB
produtos_df.isna().sum()
cod_produto 0 nome_produto 0 cod_classe_produto 0 classe_produto 0 valor 0 dtype: int64
Para as atividades relacionados a clusterização realizada pelo k-means, crie um novo dataframe (compras_clientes) com os dados obtidos entre a relação das tabelas cliente, estado, produto e compras.
# Criação da tabela compras_clientes:
#join cliente (cod_estado) e estado (codigo_estado)
#compras (cod_cliente) (cod_produto)
compras_clientes_df = compras_df.merge(clientes_df, on= "cod_cliente")
compras_clientes_produtos_df = compras_clientes_df.merge(produtos_df, on ="cod_produto")
estados_df.rename(columns={"codigo_estado":"cod_estado"}, inplace=True)
estados_df.head()
| cod_estado | nome_estado | sgl_estado | |
|---|---|---|---|
| 0 | 1 | Acre | AC |
| 1 | 2 | Alagoas | AL |
| 2 | 3 | Amapá | AP |
| 3 | 4 | Amazonas | AM |
| 4 | 5 | Bahia | BA |
compras_clientes = compras_clientes_produtos_df.merge(estados_df, on="cod_estado")
compras_clientes.head()
| cod_cliente | cod_produto | qtd_produto | valor_unitario | valor_total_compra | sexo | idade | qtd_filhos | estado_civil | cod_estado | hipertenso | diabetes | nome_produto | cod_classe_produto | classe_produto | valor | nome_estado | sgl_estado | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 0 | 1 | 1011.0 | 3 | 5.99 | 17.97 | 1 | 26 | 2 | 3 | 13 | 0 | 1 | Lustra móveis | 1 | Produtos de Limpeza | 5.99 | Minas Gerais | MG |
| 1 | 1973 | 1049.0 | 3 | 5.99 | 17.97 | 1 | 36 | 1 | 1 | 13 | 0 | 1 | Leite em pó | 3 | Alimentação | 5.99 | Minas Gerais | MG |
| 2 | 2658 | 1049.0 | 4 | 5.99 | 23.96 | 0 | 58 | 1 | 0 | 13 | 1 | 1 | Leite em pó | 3 | Alimentação | 5.99 | Minas Gerais | MG |
| 3 | 593 | 1001.0 | 3 | 22.00 | 66.00 | 1 | 18 | 3 | 0 | 13 | 1 | 0 | Amaciante | 1 | Produtos de Limpeza | 22.00 | Minas Gerais | MG |
| 4 | 647 | 1001.0 | 4 | 22.00 | 88.00 | 1 | 67 | 1 | 1 | 13 | 0 | 1 | Amaciante | 1 | Produtos de Limpeza | 22.00 | Minas Gerais | MG |
compras_clientes.info() #checando o número de linhas (ok!)
<class 'pandas.core.frame.DataFrame'> Int64Index: 2990 entries, 0 to 2989 Data columns (total 18 columns): # Column Non-Null Count Dtype --- ------ -------------- ----- 0 cod_cliente 2990 non-null int64 1 cod_produto 2990 non-null float64 2 qtd_produto 2990 non-null int64 3 valor_unitario 2990 non-null float64 4 valor_total_compra 2990 non-null float64 5 sexo 2990 non-null int64 6 idade 2990 non-null int64 7 qtd_filhos 2990 non-null int64 8 estado_civil 2990 non-null int64 9 cod_estado 2990 non-null int64 10 hipertenso 2990 non-null int64 11 diabetes 2990 non-null int64 12 nome_produto 2990 non-null object 13 cod_classe_produto 2990 non-null int64 14 classe_produto 2990 non-null object 15 valor 2990 non-null float64 16 nome_estado 2990 non-null object 17 sgl_estado 2990 non-null object dtypes: float64(4), int64(10), object(4) memory usage: 443.8+ KB
Crie uma nova base de dados a partir de compras_clientes com as colunas de idade e valor total da compra. Calcule o WCSS para esses dados e responda: qual o valor de WCSS para o terceiro cluster? PS.: Atenção para a forma de apresentação do número do cluster no python.
dados = compras_clientes.loc[:,["idade","valor_total_compra"]]
dados.head()
| idade | valor_total_compra | |
|---|---|---|
| 0 | 26 | 17.97 |
| 1 | 36 | 17.97 |
| 2 | 58 | 23.96 |
| 3 | 18 | 66.00 |
| 4 | 67 | 88.00 |
from sklearn.cluster import KMeans
def calcular_wcss(dados):
wcss = []
for k in range(1,11):
kmeans = KMeans(n_clusters = k, random_state=0)
kmeans.fit(X=dados)
wcss.append(kmeans.inertia_)
return wcss
wcss_idade_compras = calcular_wcss(dados)
# Visualizando os dados obtidos do WCSS
for i in range(len(wcss_idade_compras)):
print(f'O cluster {i+1} possui valor de WCSS de: {wcss_idade_compras[i]}')
O cluster 1 possui valor de WCSS de: 3594146.388905853 O cluster 2 possui valor de WCSS de: 1665877.0056578151 O cluster 3 possui valor de WCSS de: 1077616.8562786132 O cluster 4 possui valor de WCSS de: 725776.0404237877 O cluster 5 possui valor de WCSS de: 533118.5850935787 O cluster 6 possui valor de WCSS de: 442117.18164258613 O cluster 7 possui valor de WCSS de: 378911.908461411 O cluster 8 possui valor de WCSS de: 332389.2644378668 O cluster 9 possui valor de WCSS de: 301346.73243347835 O cluster 10 possui valor de WCSS de: 271997.07206394855
# Visualizando o gráfico do cotovelo:
import plotly.express as px #Criação de graficos dinâmnicos
import plotly.offline as py
import plotly.graph_objects as go #Para criação e concatenização de graficos
grafico_wcss = px.line( x= range(1,11),
y=wcss_idade_compras
)
fig = go.Figure(grafico_wcss)
fig.update_layout(title='Calculando o WCSS',
xaxis_title= 'Número de clusters',
yaxis_title= 'Valor do Wcss',
template = 'plotly_white'
)
fig.show()
# Aplicando o KMeans para num. de clusters igual a 4
kmeans_idade_compras = KMeans(n_clusters=4, random_state=0)
compras_clientes['cluster'] = kmeans_idade_compras.fit_predict(dados)
compras_clientes.head()
| cod_cliente | cod_produto | qtd_produto | valor_unitario | valor_total_compra | sexo | idade | qtd_filhos | estado_civil | cod_estado | hipertenso | diabetes | nome_produto | cod_classe_produto | classe_produto | valor | nome_estado | sgl_estado | cluster | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 0 | 1 | 1011.0 | 3 | 5.99 | 17.97 | 1 | 26 | 2 | 3 | 13 | 0 | 1 | Lustra móveis | 1 | Produtos de Limpeza | 5.99 | Minas Gerais | MG | 0 |
| 1 | 1973 | 1049.0 | 3 | 5.99 | 17.97 | 1 | 36 | 1 | 1 | 13 | 0 | 1 | Leite em pó | 3 | Alimentação | 5.99 | Minas Gerais | MG | 0 |
| 2 | 2658 | 1049.0 | 4 | 5.99 | 23.96 | 0 | 58 | 1 | 0 | 13 | 1 | 1 | Leite em pó | 3 | Alimentação | 5.99 | Minas Gerais | MG | 2 |
| 3 | 593 | 1001.0 | 3 | 22.00 | 66.00 | 1 | 18 | 3 | 0 | 13 | 1 | 0 | Amaciante | 1 | Produtos de Limpeza | 22.00 | Minas Gerais | MG | 3 |
| 4 | 647 | 1001.0 | 4 | 22.00 | 88.00 | 1 | 67 | 1 | 1 | 13 | 0 | 1 | Amaciante | 1 | Produtos de Limpeza | 22.00 | Minas Gerais | MG | 3 |
# Calculando os centroides de cada cluster:
centroides_clusters = kmeans_idade_compras.cluster_centers_
centroides_clusters
array([[ 32.07788391, 14.00774431],
[ 45.35185185, 186.0312963 ],
[ 60.90709583, 13.04247988],
[ 47.08173077, 78.078125 ]])
# Plotando o gráfico:
grafico = px.scatter(x = compras_clientes['idade'],
y = compras_clientes['valor_total_compra'],
color= compras_clientes['cluster'])
grafico_centroide = px.scatter(x = centroides_clusters[:,0], y = centroides_clusters[:,1], size = [7,7,7,7])
grafico_final = go.Figure(data = grafico.data + grafico_centroide.data)
grafico_final.update_layout(title='Análise de Clusters',
xaxis_title= 'Idade',
yaxis_title= 'Valor total das compras',
)
grafico_final.show()
Construa um histograma de distribuição de idades das pessoas que são hipertensas e que realizaram compra de produtos da classe "Carnes e Frios". Considere um gráfico de barras com 20 colunas.
df = compras_clientes[(compras_clientes["hipertenso"]==1) & (compras_clientes["classe_produto"]=="Carnes e Frios")]
df.head()
| cod_cliente | cod_produto | qtd_produto | valor_unitario | valor_total_compra | sexo | idade | qtd_filhos | estado_civil | cod_estado | hipertenso | diabetes | nome_produto | cod_classe_produto | classe_produto | valor | nome_estado | sgl_estado | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 17 | 1522 | 1077.0 | 1 | 34.50 | 34.50 | 0 | 48 | 0 | 0 | 13 | 1 | 0 | Queijo outros | 5 | Carnes e Frios | 34.50 | Minas Gerais | MG |
| 18 | 2375 | 1077.0 | 4 | 34.50 | 138.00 | 0 | 24 | 1 | 1 | 13 | 1 | 1 | Queijo outros | 5 | Carnes e Frios | 34.50 | Minas Gerais | MG |
| 48 | 398 | 1082.0 | 1 | 29.99 | 29.99 | 0 | 74 | 1 | 3 | 13 | 1 | 0 | Peixe | 5 | Carnes e Frios | 29.99 | Minas Gerais | MG |
| 49 | 633 | 1082.0 | 4 | 29.99 | 119.96 | 0 | 36 | 2 | 1 | 13 | 1 | 0 | Peixe | 5 | Carnes e Frios | 29.99 | Minas Gerais | MG |
| 52 | 1811 | 1084.0 | 3 | 56.99 | 170.97 | 1 | 33 | 0 | 2 | 13 | 1 | 0 | Carne vermelha | 5 | Carnes e Frios | 56.99 | Minas Gerais | MG |
import seaborn as sns
import matplotlib as mpl
import matplotlib.pyplot as plt
import numpy as np
%matplotlib inline
sns.set_theme(style="ticks")
f, ax = plt.subplots(figsize=(7, 5))
sns.histplot(df,x="idade",bins=20)
<AxesSubplot:xlabel='idade', ylabel='Count'>
Qual a proporção de homens e mulheres diabéticos que compraram produtos da classe "hortifruti"?
df2 = compras_clientes[(compras_clientes["diabetes"]==1) & (compras_clientes["classe_produto"]=="Hortifruti")]
df2.head()
| cod_cliente | cod_produto | qtd_produto | valor_unitario | valor_total_compra | sexo | idade | qtd_filhos | estado_civil | cod_estado | hipertenso | diabetes | nome_produto | cod_classe_produto | classe_produto | valor | nome_estado | sgl_estado | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 7 | 2993 | 1069.0 | 2 | 3.49 | 6.98 | 0 | 38 | 3 | 0 | 13 | 1 | 1 | Melão | 4 | Hortifruti | 3.49 | Minas Gerais | MG |
| 20 | 427 | 1060.0 | 2 | 3.50 | 7.00 | 1 | 35 | 3 | 1 | 13 | 1 | 1 | Mandioca | 4 | Hortifruti | 3.50 | Minas Gerais | MG |
| 35 | 2760 | 1065.0 | 2 | 5.99 | 11.98 | 0 | 34 | 1 | 3 | 13 | 1 | 1 | Uva | 4 | Hortifruti | 5.99 | Minas Gerais | MG |
| 56 | 464 | 1054.0 | 4 | 1.50 | 6.00 | 1 | 39 | 1 | 3 | 13 | 0 | 1 | Couve | 4 | Hortifruti | 1.50 | Minas Gerais | MG |
| 57 | 820 | 1054.0 | 2 | 1.50 | 3.00 | 1 | 57 | 2 | 1 | 13 | 0 | 1 | Couve | 4 | Hortifruti | 1.50 | Minas Gerais | MG |
df2.info()
<class 'pandas.core.frame.DataFrame'> Int64Index: 411 entries, 7 to 2986 Data columns (total 18 columns): # Column Non-Null Count Dtype --- ------ -------------- ----- 0 cod_cliente 411 non-null int64 1 cod_produto 411 non-null float64 2 qtd_produto 411 non-null int64 3 valor_unitario 411 non-null float64 4 valor_total_compra 411 non-null float64 5 sexo 411 non-null int64 6 idade 411 non-null int64 7 qtd_filhos 411 non-null int64 8 estado_civil 411 non-null int64 9 cod_estado 411 non-null int64 10 hipertenso 411 non-null int64 11 diabetes 411 non-null int64 12 nome_produto 411 non-null object 13 cod_classe_produto 411 non-null int64 14 classe_produto 411 non-null object 15 valor 411 non-null float64 16 nome_estado 411 non-null object 17 sgl_estado 411 non-null object dtypes: float64(4), int64(10), object(4) memory usage: 77.2+ KB
209 cod 0: feminino
df2[df2["sexo"]==1].info()
<class 'pandas.core.frame.DataFrame'> Int64Index: 202 entries, 20 to 2986 Data columns (total 18 columns): # Column Non-Null Count Dtype --- ------ -------------- ----- 0 cod_cliente 202 non-null int64 1 cod_produto 202 non-null float64 2 qtd_produto 202 non-null int64 3 valor_unitario 202 non-null float64 4 valor_total_compra 202 non-null float64 5 sexo 202 non-null int64 6 idade 202 non-null int64 7 qtd_filhos 202 non-null int64 8 estado_civil 202 non-null int64 9 cod_estado 202 non-null int64 10 hipertenso 202 non-null int64 11 diabetes 202 non-null int64 12 nome_produto 202 non-null object 13 cod_classe_produto 202 non-null int64 14 classe_produto 202 non-null object 15 valor 202 non-null float64 16 nome_estado 202 non-null object 17 sgl_estado 202 non-null object dtypes: float64(4), int64(10), object(4) memory usage: 30.0+ KB
202 cod 1: masculino
Qual é a classe de produtos que possui maior média de compras para as pessoas do estado de São Paulo? Informe a sua respectiva média.
df_sp = compras_clientes[(compras_clientes["nome_estado"]=="São Paulo")]
df_sp.head()
| cod_cliente | cod_produto | qtd_produto | valor_unitario | valor_total_compra | sexo | idade | qtd_filhos | estado_civil | cod_estado | hipertenso | diabetes | nome_produto | cod_classe_produto | classe_produto | valor | nome_estado | sgl_estado | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 2744 | 1371 | 1032.0 | 4 | 9.99 | 39.96 | 1 | 70 | 0 | 0 | 25 | 1 | 0 | Café | 3 | Alimentação | 9.99 | São Paulo | SP |
| 2745 | 1722 | 1032.0 | 2 | 9.99 | 19.98 | 0 | 48 | 0 | 1 | 25 | 0 | 1 | Café | 3 | Alimentação | 9.99 | São Paulo | SP |
| 2746 | 1786 | 1032.0 | 4 | 9.99 | 39.96 | 0 | 27 | 2 | 2 | 25 | 0 | 1 | Café | 3 | Alimentação | 9.99 | São Paulo | SP |
| 2747 | 177 | 1001.0 | 4 | 22.00 | 88.00 | 0 | 28 | 1 | 2 | 25 | 0 | 1 | Amaciante | 1 | Produtos de Limpeza | 22.00 | São Paulo | SP |
| 2748 | 6 | 1003.0 | 2 | 12.00 | 24.00 | 0 | 30 | 2 | 0 | 25 | 1 | 0 | Água sanitária | 1 | Produtos de Limpeza | 12.00 | São Paulo | SP |
df_sp.groupby(["classe_produto"]).mean()
| cod_cliente | cod_produto | qtd_produto | valor_unitario | valor_total_compra | sexo | idade | qtd_filhos | estado_civil | cod_estado | hipertenso | diabetes | cod_classe_produto | valor | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| classe_produto | ||||||||||||||
| Alimentação | 1351.700000 | 1036.725000 | 2.875000 | 5.814750 | 17.406000 | 0.400000 | 51.600000 | 1.375000 | 1.500000 | 25.0 | 0.425000 | 0.450000 | 3.0 | 5.814750 |
| Bebidas | 1334.250000 | 1019.250000 | 2.750000 | 4.222500 | 12.106250 | 0.625000 | 38.500000 | 2.375000 | 1.500000 | 25.0 | 0.250000 | 0.750000 | 2.0 | 4.222500 |
| Carnes e Frios | 1770.894737 | 1081.421053 | 2.789474 | 32.430526 | 82.678947 | 0.473684 | 45.105263 | 0.684211 | 1.210526 | 25.0 | 0.526316 | 0.473684 | 5.0 | 32.430526 |
| Hortifruti | 1608.750000 | 1063.357143 | 2.642857 | 3.474286 | 9.455714 | 0.392857 | 46.464286 | 1.250000 | 1.464286 | 25.0 | 0.607143 | 0.535714 | 4.0 | 3.474286 |
| Produtos de Limpeza | 1434.000000 | 1007.956522 | 2.217391 | 9.513913 | 22.088696 | 0.608696 | 47.826087 | 1.173913 | 1.478261 | 25.0 | 0.478261 | 0.608696 | 1.0 | 9.513913 |
Qual é a quantidade de casados e hipertensos estão presentes no cluster 0? (cluster 0 = cluster 2)
compras_clientes[(compras_clientes["hipertenso"]==1) & (compras_clientes["estado_civil"]==1) & (compras_clientes["cluster"]==2)].count()
cod_cliente 193 cod_produto 193 qtd_produto 193 valor_unitario 193 valor_total_compra 193 sexo 193 idade 193 qtd_filhos 193 estado_civil 193 cod_estado 193 hipertenso 193 diabetes 193 nome_produto 193 cod_classe_produto 193 classe_produto 193 valor 193 nome_estado 193 sgl_estado 193 cluster 193 dtype: int64
Qual é o número total de diabéticos para o cluster 3?
compras_clientes[(compras_clientes["diabetes"]==1) & (compras_clientes["cluster"]==3)].count()
cod_cliente 109 cod_produto 109 qtd_produto 109 valor_unitario 109 valor_total_compra 109 sexo 109 idade 109 qtd_filhos 109 estado_civil 109 cod_estado 109 hipertenso 109 diabetes 109 nome_produto 109 cod_classe_produto 109 classe_produto 109 valor 109 nome_estado 109 sgl_estado 109 cluster 109 dtype: int64
Quantos produtos distintos existem no dataset de mercado?
#lista_compras
set_list = []
for lista in lista_compras:
for item in lista:
if item not in set_list:
set_list.append(item)
set_list
['shrimp', 'almonds', 'avocado', 'vegetables mix', 'green grapes', 'whole weat flour', 'yams', 'cottage cheese', 'energy drink', 'tomato juice', 'low fat yogurt', 'green tea', 'honey', 'salad', 'mineral water', 'salmon', 'antioxydant juice', 'frozen smoothie', 'spinach', 'olive oil', 'burgers', 'meatballs', 'eggs', 'nan', 'chutney', 'turkey', 'milk', 'energy bar', 'whole wheat rice', 'whole wheat pasta', 'french fries', 'soup', 'light cream', 'shallot', 'frozen vegetables', 'spaghetti', 'pet food', 'cookies', 'cooking oil', 'champagne', 'chocolate', 'chicken', 'oil', 'fresh tuna', 'tomatoes', 'black tea', 'extra dark chocolate', 'protein bar', 'red wine', 'pasta', 'pepper', 'shampoo', 'rice', 'sparkling water', 'ham', 'body spray', 'pancakes', 'grated cheese', 'white wine', 'toothpaste', 'parmesan cheese', 'fresh bread', 'ground beef', 'escalope', 'herb & pepper', 'tomato sauce', 'magazines', 'strawberries', 'strong cheese', 'pickles', 'cake', 'hot dogs', 'brownies', 'cereals', 'clothes accessories', 'bug spray', 'muffins', 'light mayo', 'gums', 'soda', 'cider', 'corn', 'yogurt cake', 'mint', 'butter', 'asparagus', 'french wine', 'salt', 'tea', 'barbecue sauce', 'mayonnaise', 'zucchini', 'carrots', 'mushroom cream sauce', 'candy bars', 'chili', 'mashed potato', 'nonfat milk', 'water spray', 'chocolate bread', 'mint green tea', 'eggplant', 'blueberries', 'bacon', 'fromage blanc', 'gluten free bar', 'dessert wine', 'flax seed', 'hand protein bar', 'sandwich', 'babies food', 'melons', 'cauliflower', 'green beans', 'ketchup', 'bramble', 'burger sauce', 'oatmeal', ' asparagus', 'cream', 'napkins']
len(set_list) #este número menos 1, pq contém "nan" #121 - 1 = 120 items
121
Qual o número de compras que foram realizadas contendo espaguete e água mineral na mesma compra?
df_prod_mercado.loc[(df_prod_mercado['spaghetti'] == True) & (df_prod_mercado['mineral water'] == True)].count()
asparagus 448
almonds 448
antioxydant juice 448
asparagus 448
avocado 448
...
whole wheat pasta 448
whole wheat rice 448
yams 448
yogurt cake 448
zucchini 448
Length: 120, dtype: int64
Após a implantação de todas as etapas do processo do Big Data, os analistas identificaram a necessidade de entender melhor a relação entre os produtos comprados pelos clientes. A ideia é encontrar padrões ocultos nos dados, que possam auxiliar na tomada de decisão e assim criar promoções, kits de vendas e melhorar disponibilização de produtos nas prateleiras dos supermercados, por exemplo. Para isso, antes de implementar o modelo em produção, os analistas vão realizar uma POC com dados de vendas de produtos de outra rede de supermercados e, em seguida, aplicar o modelo nos dados de produção do supermercado.
Atividades do enunciado II
Os alunos deverão desempenhar as seguintes atividades:
from mlxtend.preprocessing import TransactionEncoder
mercado_df.head()
| Id | product_1 | product_2 | product_3 | product_4 | product_5 | product_6 | product_7 | product_8 | product_9 | ... | product_11 | product_12 | product_13 | product_14 | product_15 | product_16 | product_17 | product_18 | product_19 | product_20 | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 0 | 0 | shrimp | almonds | avocado | vegetables mix | green grapes | whole weat flour | yams | cottage cheese | energy drink | ... | low fat yogurt | green tea | honey | salad | mineral water | salmon | antioxydant juice | frozen smoothie | spinach | olive oil |
| 1 | 1 | burgers | meatballs | eggs | NaN | NaN | NaN | NaN | NaN | NaN | ... | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN |
| 2 | 2 | chutney | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | ... | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN |
| 3 | 3 | turkey | avocado | NaN | NaN | NaN | NaN | NaN | NaN | NaN | ... | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN |
| 4 | 4 | mineral water | milk | energy bar | whole wheat rice | green tea | NaN | NaN | NaN | NaN | ... | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN |
5 rows × 21 columns
mercado_df.columns
Index(['Id', 'product_1', 'product_2', 'product_3', 'product_4', 'product_5',
'product_6', 'product_7', 'product_8', 'product_9', 'product_10',
'product_11', 'product_12', 'product_13', 'product_14', 'product_15',
'product_16', 'product_17', 'product_18', 'product_19', 'product_20'],
dtype='object')
# O algoritmo de regras de associação necessita que o input de dados seja em formato de lista contendo indicador de true or false para cada produto.
# Desta forma, temos que realizar tratamento de dados no dataset para satisfazer essa premissa.
# Drop na coluna Id:
mercado_df.drop(['Id'], axis=1,inplace=True)
mercado_df.head()
| product_1 | product_2 | product_3 | product_4 | product_5 | product_6 | product_7 | product_8 | product_9 | product_10 | product_11 | product_12 | product_13 | product_14 | product_15 | product_16 | product_17 | product_18 | product_19 | product_20 | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 0 | shrimp | almonds | avocado | vegetables mix | green grapes | whole weat flour | yams | cottage cheese | energy drink | tomato juice | low fat yogurt | green tea | honey | salad | mineral water | salmon | antioxydant juice | frozen smoothie | spinach | olive oil |
| 1 | burgers | meatballs | eggs | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN |
| 2 | chutney | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN |
| 3 | turkey | avocado | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN |
| 4 | mineral water | milk | energy bar | whole wheat rice | green tea | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN |
# Temos que acessar cada item dentro do dataframe e inserir em uma lista
lista_compras = []
for i in range(len(mercado_df)):
lista_compras.append([str(mercado_df.values[i, j]) for j in range(20)])
#Visualizando lista de compras gerada
#lista_compras
# Criando lista de produtos com o indicador True ou False:
te = TransactionEncoder()
te_array = te.fit(lista_compras).transform(lista_compras)
#visualizando lista de produtos criada
te_array
array([[False, True, True, ..., True, False, False],
[False, False, False, ..., False, False, False],
[False, False, False, ..., False, False, False],
...,
[False, False, False, ..., False, False, False],
[False, False, False, ..., False, False, False],
[False, False, False, ..., False, True, False]])
df_prod_mercado = pd.DataFrame(te_array, columns = te.columns_)
#Visualizando o dataframe
df_prod_mercado
| asparagus | almonds | antioxydant juice | asparagus | avocado | babies food | bacon | barbecue sauce | black tea | blueberries | ... | turkey | vegetables mix | water spray | white wine | whole weat flour | whole wheat pasta | whole wheat rice | yams | yogurt cake | zucchini | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 0 | False | True | True | False | True | False | False | False | False | False | ... | False | True | False | False | True | False | False | True | False | False |
| 1 | False | False | False | False | False | False | False | False | False | False | ... | False | False | False | False | False | False | False | False | False | False |
| 2 | False | False | False | False | False | False | False | False | False | False | ... | False | False | False | False | False | False | False | False | False | False |
| 3 | False | False | False | False | True | False | False | False | False | False | ... | True | False | False | False | False | False | False | False | False | False |
| 4 | False | False | False | False | False | False | False | False | False | False | ... | False | False | False | False | False | False | True | False | False | False |
| ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... |
| 7496 | False | False | False | False | False | False | False | False | False | False | ... | False | False | False | False | False | False | False | False | False | False |
| 7497 | False | False | False | False | False | False | False | False | False | False | ... | False | False | False | False | False | False | False | False | False | False |
| 7498 | False | False | False | False | False | False | False | False | False | False | ... | False | False | False | False | False | False | False | False | False | False |
| 7499 | False | False | False | False | False | False | False | False | False | False | ... | False | False | False | False | False | False | False | False | False | False |
| 7500 | False | False | False | False | False | False | False | False | False | False | ... | False | False | False | False | False | False | False | False | True | False |
7501 rows × 121 columns
# Ao transformar os dados, as colunas que possuiam valores ausentes do tipo "Nan" foram incluidads como um produto do mercado. No entanto, isso não é verdadeiro. Dessa forma, vamos eliminar essa coluna do nosso dataframe.
df_prod_mercado.drop(columns='nan', inplace=True)
#visualizando conjunto de dados
df_prod_mercado
| asparagus | almonds | antioxydant juice | asparagus | avocado | babies food | bacon | barbecue sauce | black tea | blueberries | ... | turkey | vegetables mix | water spray | white wine | whole weat flour | whole wheat pasta | whole wheat rice | yams | yogurt cake | zucchini | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 0 | False | True | True | False | True | False | False | False | False | False | ... | False | True | False | False | True | False | False | True | False | False |
| 1 | False | False | False | False | False | False | False | False | False | False | ... | False | False | False | False | False | False | False | False | False | False |
| 2 | False | False | False | False | False | False | False | False | False | False | ... | False | False | False | False | False | False | False | False | False | False |
| 3 | False | False | False | False | True | False | False | False | False | False | ... | True | False | False | False | False | False | False | False | False | False |
| 4 | False | False | False | False | False | False | False | False | False | False | ... | False | False | False | False | False | False | True | False | False | False |
| ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... |
| 7496 | False | False | False | False | False | False | False | False | False | False | ... | False | False | False | False | False | False | False | False | False | False |
| 7497 | False | False | False | False | False | False | False | False | False | False | ... | False | False | False | False | False | False | False | False | False | False |
| 7498 | False | False | False | False | False | False | False | False | False | False | ... | False | False | False | False | False | False | False | False | False | False |
| 7499 | False | False | False | False | False | False | False | False | False | False | ... | False | False | False | False | False | False | False | False | False | False |
| 7500 | False | False | False | False | False | False | False | False | False | False | ... | False | False | False | False | False | False | False | False | True | False |
7501 rows × 120 columns
# Nesta etapa vamos gerar os itens sets mais frequentes no nosso dataframe. Para isso, vamos utiizar a biblioteca apriori.
from mlxtend.frequent_patterns import apriori
frequent_itemsets = apriori(df_prod_mercado, min_support=0.15, use_colnames=True) # Seleciono apenas suporte de 0,15
frequent_itemsets
| support | itemsets | |
|---|---|---|
| 0 | 0.163845 | (chocolate) |
| 1 | 0.179709 | (eggs) |
| 2 | 0.170911 | (french fries) |
| 3 | 0.238368 | (mineral water) |
| 4 | 0.174110 | (spaghetti) |
# mesmo procedimento, agora com min_support=0.05:
frequent_itemsets = apriori(df_prod_mercado, min_support=0.05, use_colnames=True)
frequent_itemsets
| support | itemsets | |
|---|---|---|
| 0 | 0.087188 | (burgers) |
| 1 | 0.081056 | (cake) |
| 2 | 0.059992 | (chicken) |
| 3 | 0.163845 | (chocolate) |
| 4 | 0.080389 | (cookies) |
| 5 | 0.051060 | (cooking oil) |
| 6 | 0.179709 | (eggs) |
| 7 | 0.079323 | (escalope) |
| 8 | 0.170911 | (french fries) |
| 9 | 0.063325 | (frozen smoothie) |
| 10 | 0.095321 | (frozen vegetables) |
| 11 | 0.052393 | (grated cheese) |
| 12 | 0.132116 | (green tea) |
| 13 | 0.098254 | (ground beef) |
| 14 | 0.076523 | (low fat yogurt) |
| 15 | 0.129583 | (milk) |
| 16 | 0.238368 | (mineral water) |
| 17 | 0.065858 | (olive oil) |
| 18 | 0.095054 | (pancakes) |
| 19 | 0.071457 | (shrimp) |
| 20 | 0.050527 | (soup) |
| 21 | 0.174110 | (spaghetti) |
| 22 | 0.068391 | (tomatoes) |
| 23 | 0.062525 | (turkey) |
| 24 | 0.058526 | (whole wheat rice) |
| 25 | 0.052660 | (chocolate, mineral water) |
| 26 | 0.050927 | (eggs, mineral water) |
| 27 | 0.059725 | (spaghetti, mineral water) |
frequent_itemsets.sort_values(by=["support"], ascending=False)
| support | itemsets | |
|---|---|---|
| 16 | 0.238368 | (mineral water) |
| 6 | 0.179709 | (eggs) |
| 21 | 0.174110 | (spaghetti) |
| 8 | 0.170911 | (french fries) |
| 3 | 0.163845 | (chocolate) |
| 12 | 0.132116 | (green tea) |
| 15 | 0.129583 | (milk) |
| 13 | 0.098254 | (ground beef) |
| 10 | 0.095321 | (frozen vegetables) |
| 18 | 0.095054 | (pancakes) |
| 0 | 0.087188 | (burgers) |
| 1 | 0.081056 | (cake) |
| 4 | 0.080389 | (cookies) |
| 7 | 0.079323 | (escalope) |
| 14 | 0.076523 | (low fat yogurt) |
| 19 | 0.071457 | (shrimp) |
| 22 | 0.068391 | (tomatoes) |
| 17 | 0.065858 | (olive oil) |
| 9 | 0.063325 | (frozen smoothie) |
| 23 | 0.062525 | (turkey) |
| 2 | 0.059992 | (chicken) |
| 27 | 0.059725 | (spaghetti, mineral water) |
| 24 | 0.058526 | (whole wheat rice) |
| 25 | 0.052660 | (chocolate, mineral water) |
| 11 | 0.052393 | (grated cheese) |
| 5 | 0.051060 | (cooking oil) |
| 26 | 0.050927 | (eggs, mineral water) |
| 20 | 0.050527 | (soup) |
# Após a criação dos itens mais frequentes, o proximo passo é criar as regras de associação. Vamos importar a biblioteca association_rules para gerar as regras.
from mlxtend.frequent_patterns import association_rules
regras = association_rules(frequent_itemsets, metric='confidence',min_threshold=0.2) # 20% das vezes as regras aconteceram (confiança de 20%)
#visualizando as regras criadas
regras
| antecedents | consequents | antecedent support | consequent support | support | confidence | lift | leverage | conviction | |
|---|---|---|---|---|---|---|---|---|---|
| 0 | (mineral water) | (chocolate) | 0.238368 | 0.163845 | 0.052660 | 0.220917 | 1.348332 | 0.013604 | 1.073256 |
| 1 | (chocolate) | (mineral water) | 0.163845 | 0.238368 | 0.052660 | 0.321400 | 1.348332 | 0.013604 | 1.122357 |
| 2 | (mineral water) | (eggs) | 0.238368 | 0.179709 | 0.050927 | 0.213647 | 1.188845 | 0.008090 | 1.043158 |
| 3 | (eggs) | (mineral water) | 0.179709 | 0.238368 | 0.050927 | 0.283383 | 1.188845 | 0.008090 | 1.062815 |
| 4 | (mineral water) | (spaghetti) | 0.238368 | 0.174110 | 0.059725 | 0.250559 | 1.439085 | 0.018223 | 1.102008 |
| 5 | (spaghetti) | (mineral water) | 0.174110 | 0.238368 | 0.059725 | 0.343032 | 1.439085 | 0.018223 | 1.159314 |
Analisando o LIFT de cada regra de associação, vemos que as regras mais fortes são: